﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Bymed.SpineScan.Service.Shared;
using Bymed.RegistrationCodeManager.Service.DataModel;
using Bymed.RegistrationCodeManager.Service.Shared;

namespace Bymed.SpineScan.Service
{
    public enum GenuineCheckStatus
    {
        Unchecked,
        Passed,
        Failed
    }

    public class GenuineCheckService
    {
        public GenuineCheckStatus CurrentCheckStatus { get; set; }

        public GenuineCheckService()
        {
            CurrentCheckStatus = GenuineCheckStatus.Unchecked;
        }

        /// <summary>
        /// Trying to get the Serial Number from the message comes from device.
        /// If the format matched, then the Serial Number will be returned.
        /// Otherwise, empty string will be returned.
        /// </summary>
        /// <param name="message">The message comes from device.</param>
        /// <returns>If the format matched, then the Serial Number will be returned.
        /// Otherwise, empty string will be returned.</returns>
        public string GetSerialNumber(string message)
        {
            message = message.Trim();
            var pattern = @"SN=\d+\s+VER=\d+";
            var regex = new Regex(pattern, RegexOptions.IgnoreCase);
            var matches = regex.Matches(message);

            if (matches.Count > 0)
            {
                return message;
            }
            else
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Save the input serial number comes from device as a encrypted string.
        /// </summary>
        /// <param name="inputSerialNumber">The input serial number comes from device.</param>
        public void SaveSerialNumber(string inputSerialNumber)
        {
            ConfigFileUtility.ChangeValue(ConfigurationConstant.DeviceSerialNumber, RegistrationCodeManagerUtility.EncryptString(inputSerialNumber));
            ConfigFileUtility.RefreshAppSettingsSection();
        }

        /// <summary>
        /// Get the saved the serial number.
        /// </summary>
        /// <returns>The saved serial number.</returns>
        public string GetSerialNumber()
        {
            return RegistrationCodeManagerUtility.DecryptString((string)ConfigFileUtility.GetValue(ConfigurationConstant.DeviceSerialNumber));
        }

        /// <summary>
        /// Gets the first Ethernet Mac Address on current computer.
        /// </summary>
        /// <returns></returns>
        public string GetComputerName()
        {
            return RegistrationCodeManagerUtility.GetFirstEthernetMacAddress();
        }

        /// <summary>
        /// Check the input serial number comes from device is the same as current one.
        /// </summary>
        /// <param name="inputSerialNumber">The input serial number comes from device.</param>
        /// <returns>GenuineCheckStatus</returns>
        public GenuineCheckStatus Check(string inputSerialNumber)
        {
            var storedRegistrationCode = (string)ConfigFileUtility.GetValue(ConfigurationConstant.RegistrationCode);
            var registrationCode = RegistrationCodeManagerUtility.DecryptRegistrationCode(storedRegistrationCode);

            if (registrationCode != null)
            {
                var inputMacAddress = registrationCode.ComputerNumber;
                var inputAuthorisedUsageCount = registrationCode.AuthorisedUsageCount;

                var currentSerialNumber = registrationCode.DeviceNumber;
                var currentMacAddress = GetComputerName();
                var currentAuthorisedUsageCount = GeneralUtility.GetAvailableAuthorisedUsageCount();

                // Check if current Serial Number is the same as the one comes from device as well as the MacAddress.
                if (currentSerialNumber == inputSerialNumber &&
                    currentMacAddress == inputMacAddress && 
                    currentAuthorisedUsageCount <= inputAuthorisedUsageCount &&
                    currentAuthorisedUsageCount != 0)
                {
                    CurrentCheckStatus = GenuineCheckStatus.Passed;
                }
                else
                {
                    CurrentCheckStatus = GenuineCheckStatus.Failed;
                }
            }
            else
            {
                CurrentCheckStatus = GenuineCheckStatus.Failed;
            }

            return CurrentCheckStatus;
        }
    }
}
